﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using JelloPhysics;
using Microsoft.Xna.Framework;
using System.Drawing;
using System.Threading;
using System.Runtime.InteropServices;
using System.Text;

namespace PhysicsDemo
{
    internal class FallingBody : PressureBody
    {
        public FallingBody(World w, ClosedShape s, float massPerPoint, float gasPressure, float shapeSpringK, float shapeSpringDamp, float edgeSpringK, float edgeSpringDamp, Vector2 pos, float angle, Vector2 scale)
            : base(w, s, massPerPoint, gasPressure, shapeSpringK, shapeSpringDamp, edgeSpringK, edgeSpringDamp, pos, angle, scale, false)
        {
        }

        public override void accumulateExternalForces()
        {
            base.accumulateExternalForces();
            for (int i = 0; i < base.mPointMasses.Count; i++)
            {
                PointMass local1 = base.mPointMasses[i];
                local1.Force += new Vector2(0f, -9.8f * base.mPointMasses[i].Mass);
            }
        }
    }

    public sealed class Polygon
    {
        public Brush Fill = null;   // 填充色
        public Brush Stroke = null; // 边框色
        public float StrokeThickness = 4; // 边框线宽

        private List<Point> PointsList = null; // 边界点集

        public List<Point> Points
        {
            get
            {
                return PointsList;
            }
            set
            {
                PointsList = value;
            }
        }
    }

    [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
    public struct TimeTick
    {
        public const long TicksPerMillisecond = 0x2710L;
        private const double MillisecondsPerTick = 0.0001;
        //public const long TicksPerSecond = 0x989680L;
        private const double SecondsPerTick = 1E-07;
        //public const long TicksPerMinute = 0x23c34600L;
        //private const double MinutesPerTick = 1.6666666666666667E-09;
        //public const long TicksPerHour = 0x861c46800L;
        //private const double HoursPerTick = 2.7777777777777777E-11;
        //public const long TicksPerDay = 0xc92a69c000L;
        //private const double DaysPerTick = 1.1574074074074074E-12;
        private const int MillisPerSecond = 0x3e8;
        //private const int MillisPerMinute = 0xea60;
        //private const int MillisPerHour = 0x36ee80;
        //private const int MillisPerDay = 0x5265c00;
        //private const long MaxSeconds = 0xd6bf94d5e5L;
        //private const long MinSeconds = -922337203685L;
        //private const long MaxMilliSeconds = 0x346dc5d638865L;
        private const long MinMilliSeconds = -922337203685477L;
        public static readonly TimeTick Zero;
        public static readonly TimeTick MaxValue;
        public static readonly TimeTick MinValue;

        internal long _ticks;

        static TimeTick()
        {
            Zero = new TimeTick(0L);
            MaxValue = new TimeTick(0x7fffffffffffffffL);
            MinValue = new TimeTick(-9223372036854775808L);
        }

        public TimeTick(long ticks)
        {
            this._ticks = ticks;
        }

        public double TotalMilliseconds
        {
            get
            {
                double num = this._ticks * MillisecondsPerTick;
                if (num > -MinMilliSeconds)
                {
                    return -MinMilliSeconds;
                }
                if (num < MinMilliSeconds)
                {
                    return MinMilliSeconds;
                }
                return num;
            }
        }

        public override int GetHashCode()
        {
            return (((int)this._ticks) ^ ((int)(this._ticks >> 0x20)));
        }

        public override bool Equals(object value)
        {
            return ((value is TimeTick) && (this._ticks == ((TimeTick)value)._ticks));
        }

        public bool Equals(TimeTick obj)
        {
            return (this._ticks == obj._ticks);
        }

        public static bool Equals(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks == t2._ticks);
        }

        public double TotalSeconds
        {
            get
            {
                return (this._ticks * SecondsPerTick);
            }
        }

        public int Milliseconds
        {
            get
            {
                return (int)((this._ticks / TicksPerMillisecond) % MillisPerSecond);
            }
        }
 
        public long Ticks
        {
            get
            {
                return this._ticks;
            }
        }

        public TimeTick Subtract(TimeTick ts)
        {
            long ticks = this._ticks - ts._ticks;
            if (((this._ticks >> 0x3f) != (ts._ticks >> 0x3f))
                && ((this._ticks >> 0x3f) != (ticks >> 0x3f)))
            {
                throw new OverflowException(("Overflow_TimeSpanTooLong"));
            }
            return new TimeTick(ticks);
        }

        public TimeTick Add(TimeTick ts)
        {
            long ticks = this._ticks + ts._ticks;
            if (((this._ticks >> 0x3f) == (ts._ticks >> 0x3f))
                && ((this._ticks >> 0x3f) != (ticks >> 0x3f)))
            {
                throw new OverflowException("Overflow_TimeSpanTooLong");
            }
            return new TimeTick(ticks);
        }

        public static TimeTick operator -(TimeTick t)
        {
            if (t._ticks == MinValue._ticks)
            {
                throw new OverflowException(("Overflow_NegateTwosCompNum"));
            }
            return new TimeTick(-t._ticks);
        }

        public static TimeTick operator -(TimeTick t1, TimeTick t2)
        {
            return t1.Subtract(t2);
        }

        public static TimeTick operator +(TimeTick t)
        {
            return t;
        }

        public static TimeTick operator +(TimeTick t1, TimeTick t2)
        {
            return t1.Add(t2);
        }

        public static bool operator ==(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks == t2._ticks);
        }

        public static bool operator !=(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks != t2._ticks);
        }

        public static bool operator <(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks < t2._ticks);
        }

        public static bool operator <=(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks <= t2._ticks);
        }

        public static bool operator >(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks > t2._ticks);
        }

        public static bool operator >=(TimeTick t1, TimeTick t2)
        {
            return (t1._ticks >= t2._ticks);
        }

        public static TimeTick FromTicks(long value)
        {
            return new TimeTick(value);
        }

        public static TimeTick FromSeconds(double value)
        {
            return Interval(value, MillisPerSecond);
        }

        public static TimeTick FromMilliseconds(double value)
        {
            return Interval(value, 1);
        }

        private static TimeTick Interval(double value, int scale)
        {
            if (double.IsNaN(value))
            {
                throw new ArgumentException(("Arg_CannotBeNaN"));
            }
            double num = value * scale;
            double num2 = num + ((value >= 0.0) ? 0.5 : -0.5);
            if ((num2 > -MinMilliSeconds) || (num2 < MinMilliSeconds))
            {
                throw new OverflowException(("Overflow_TimeTickTooLong"));
            }
            return new TimeTick(((long)num2) * TicksPerMillisecond);
        }

    }

    static class Program
    {
        static MainForm mainForm = null;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            mainForm = new MainForm();
            Application.Idle += new EventHandler(Application_Idle);
            Application.Run(mainForm);
        }

        static void Application_Idle(object sender, EventArgs e)
        {
            if (mainForm != null)
            {
                mainForm.OnIdle();
            }
            Thread.Sleep(10);
        }
    }
}
